package com.ficus.road.maintain.third.zh.roadgps;

import com.alibaba.fastjson.JSONArray;
import com.ficus.road.maintain.core.model.Company;
import com.ficus.road.maintain.core.model.RoadInfo;
import com.ficus.road.maintain.core.model.RoadTypeEnum;
import com.ficus.road.maintain.core.model.zh.roadgps.BasicRoadZH;
import com.ficus.road.maintain.dao.CompanyDao;
import com.ficus.road.maintain.dao.RoadInfoDao;
import com.ficus.road.maintain.service.TheoryGpsService;
import com.ficus.road.maintain.third.zh.BaseZH;
import com.google.common.base.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author xiawen yang
 * @date 2022/3/30 下午3:50
 */
@Component
@Slf4j
public class ZHBasicRoad extends BaseZH {

    @Autowired
    private RoadInfoDao roadInfoDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private ZHCityAndDirectRoad zhCityAndDirectRoad;
    @Autowired
    private ZHTownRoad zhTownRoad;
    @Autowired
    private TheoryGpsService theoryGpsService;
    @Value("${zhonghai.syncRoadInfo}")
    private Boolean syncRoadInfo;

    private Map<String, String> companyIdNameMap = new ConcurrentHashMap<>();

    @PostConstruct
    void init() {
        arg0 = "ytkjGetRoadBaseInfoData";
        arg1 = "{}";
//        arg0 = "ytkjGetCompanyInfo";
        errMsg = "调用中海接口获取道路基础数据异常!";
        successMsg = "调用中海接口获取道路基础数据成功!";
        companyIdNameMap = companyDao.findAll().stream().filter(item -> ObjectUtils.isNotEmpty(item.getName())).collect(Collectors.toMap(Company::getId, Company::getName));
        if (syncRoadInfo) {
            refreshRoadLayer();
        }
    }

    public void refreshBasicRoadInfo() {
        Date date = new Date();
        String basicRoadStr = getZHData();
        if (ObjectUtils.isEmpty(basicRoadStr)) {
            return;
        }
        List<BasicRoadZH> basicRoadZHList = JSONArray.parseArray(basicRoadStr, BasicRoadZH.class);
        List<RoadInfo> roadInfoList = roadInfoDao.findAll();
        // 这里用parallelStream有问题
        basicRoadZHList.stream().forEach(zh -> {
            List<RoadInfo> filterList = roadInfoList
                    .stream()
                    .filter(entity -> Objects.equal(entity.getSecNum(), zh.getRoadid()) && Objects.equal(entity.getUnitId(), zh.getProjectid())
                            && Objects.equal(entity.getStartStake(), zh.getStartlocation()) && Objects.equal(entity.getEndStake(), zh.getEndlocation())
                            && Objects.equal(entity.getTown(), zh.getTown()))
                    .collect(Collectors.toList());
            if (filterList.size() > 1) {
//                System.out.println(zh.getRoadid() + "_" + zh.getProjectid() + "_" + filterList.size());
            }
            if (filterList.size() == 1) {
                RoadInfo roadInfo = filterList.get(0);
                roadInfo.setRoadType(getRoadType(zh.getRoadtype()));
                roadInfo.setSecLen(zh.getLength());
                roadInfo.setStartEndPoint(zh.getLocationdesc());
                roadInfo.setTown(zh.getTown());
                roadInfo.setDistrictId(zh.getTowncode());
                roadInfo.setCompanyName(companyIdNameMap.get(zh.getUnitidcode()));
                roadInfo.setModificationTime(date);
                roadInfoDao.saveOrUpdate(roadInfo);
            } else if (filterList.size() == 0) {
                // 添加新路
                RoadInfo roadInfo = RoadInfo.builder()
                        .id(zh.getProjectid() + "_" + zh.getRoadid() + "_" + zh.getStartlocation() + "_" + zh.getEndlocation())
                        .secNum(zh.getRoadid())
                        .roadType(getRoadType(zh.getRoadtype()))
                        .unitId(zh.getProjectid())
                        .companyId(zh.getUnitidcode())
                        .roadName(zh.getRoadname())
                        .startStake(zh.getStartlocation())
                        .endStake(zh.getEndlocation())
                        .startEndPoint(zh.getLocationdesc())
                        .companyName(companyIdNameMap.get(zh.getUnitidcode()))
                        .town(zh.getTown())
                        .districtId(zh.getTowncode())
                        .modificationTime(date)
                        .build();
                roadInfoDao.saveOrUpdate(roadInfo);
            }
            // 更新公司标段信息(company, unit)
            String companyId = zh.getUnitidcode();
            String companyName = zh.getUnitid();
            String unitId = zh.getProjectid();
            if (StringUtils.isNotBlank(companyId)) {
                Company fetch = companyDao.fetch(companyId);
                if (fetch == null) {
                    fetch = new Company();
                    fetch.setId(companyId);
                    if (StringUtils.isNotBlank(companyName) && companyName.length() > 6) {
                        fetch.setName(companyName);
                    } else {
                        fetch.setShortName(companyName);
                    }
                    fetch.setUnits(Set.of(unitId));
                } else {
                    if (StringUtils.isNotBlank(companyName) && companyName.length() > 6) {
                        fetch.setName(companyName);
                    } else {
                        fetch.setShortName(companyName);
                    }
                    Set<String> units = fetch.getUnits();
                    if (units.isEmpty()) {
                        units = new HashSet<>();
                    }
                    units.add(unitId);
                    fetch.setUnits(units);
                }
//                companyDao.saveOrUpdate(fetch);
            }
        });
        // 删除操作
//        List<String> zhIdList = basicRoadZHList.stream().map(item -> item.getProjectid() + "_" + item.getRoadid() + "_" + item.getStartlocation() + "_" + item.getEndlocation()).collect(Collectors.toList());
//        List<String> dbIdList = roadInfoList.stream().map(item -> item.getId()).collect(Collectors.toList());
        // 差集 -> 移除db中的旧数据
//        dbIdList.removeAll(zhIdList);
//        dbIdList.forEach(id -> {
//            roadInfoDao.deleteById(id);
//        });
    }

    public RoadTypeEnum getRoadType(String roadType) {
        RoadTypeEnum res = null;
        switch (roadType) {
            case "城市道路":
                res = RoadTypeEnum.HIGHWAY;
                break;
            case "直管公路":
                res = RoadTypeEnum.DIRECT;
                break;
            case "农村公路":
                res = RoadTypeEnum.ROAD;
                break;
            default:
                break;
        }
        return res;
    }

    @Scheduled(cron = "0 10 8 * * ?", zone = "GMT+8:00")
//    @Scheduled(cron = "0/5 * * * * ?", zone = "GMT+8:00")
    public void refreshRoadLayer() {
        init();
        log.info("开始更新中海图层");
        long l = System.currentTimeMillis();
        refreshBasicRoadInfo();
        zhCityAndDirectRoad.refreshCityRoadInfo();
        zhCityAndDirectRoad.refreshDirectRoadInfo();
        zhTownRoad.refreshTownRoadInfo();
        log.info("更新图层耗时: {}s", (System.currentTimeMillis() - l) / 1000);
    }
}
